package com.tt.aspect;

import com.tt.annotation.NoRepeatSubmit;
import com.tt.common.exception.TtException;
import com.tt.common.page.TtResult;
import com.tt.jedis.JedisClient;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 表单防重复提交AOP
 * @author 青青
 */
@Slf4j
@Aspect
@Component
public class NoRepeatSubmitAspect
{
    @Autowired
    private JedisClient jedisClient;


    /**
     * execution(execute表达式匹配要拦截的方法) && @annotation(noRepeatSubmit)
     * @param pjp
     * @param noRepeatSubmit
     * @return
     */
    @Around("@annotation(noRepeatSubmit)")
    public Object doAround(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit)
    {
        try
        {
            //请求的参数
            Object[] args = pjp.getArgs();
            log.info("请求的参数：{}",args);

            // 接收到请求，记录请求内容
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();

            // 根据ip地址、请求路径、请求参数、token等拼接成字符串，作为key值
            String key = String.format("REQUEST_FORM_%s_%s_%s", request.getRemoteAddr(), request.getRequestURL(),request.getParameter("time"));

            // 获得当前时间作为value
            long now = System.currentTimeMillis();

            // 判断是否重复提交
            if (jedisClient.exists(key))
            {
                // 上次表单提交时间
                long lastTime = Long.parseLong(jedisClient.get(key));

                // 如果现在距离上次提交时间小于设置的默认时间 则 判断为重复提交  否则 正常提交
                if ((now - lastTime) < noRepeatSubmit.time())
                {
                    return TtResult.build(500,"请勿重复提交!");
                }
            }
            // 如果不存在key，在redis中新建key-value
            jedisClient.setEx(key,30, String.valueOf(now));
            return pjp.proceed();
        } catch (TtException e)
        {
            throw new TtException("异常为："+e.getMessage());
        } catch (Throwable e)
        {
            log.error("校验表单重复提交时异常: {}", e.getMessage());
            throw new TtException("校验表单重复提交时异常!");
        }
    }
}
